package com.qingcheng.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.qingcheng.dao.BrandMapper;
import com.qingcheng.dao.SpecMapper;
import com.qingcheng.service.goods.SkuSearchService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;


import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SkuSearchServiceImpl implements SkuSearchService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private SpecMapper specMapper;


    @Override
    public Map search(Map<String, String> searchMap) {

        /**
         * SearchRequest： 查询请求对象
         * SearchResponse：查询响应对象
         * SearchSourceBuilder：查询源构建器
         * MatchQueryBuilder: 匹配查询构造器 设置搜索关键字
         * */
        //1.封装查询请求
        SearchRequest searchRequest = new SearchRequest("sku");
        searchRequest.types("doc");//创建查询器
        //查询源构建器
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //构建bool查询构造器
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //1.1关键字搜索
        MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("name", searchMap.get("keyword"));
        boolQueryBuilder.must(matchQuery);
        //1.2商品分类过滤
        if (searchMap.get("category") != null) {//categoryName
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("categoryName", searchMap.get("category"));//categoryName
            boolQueryBuilder.filter(termQueryBuilder);
        }
        searchSourceBuilder.query(boolQueryBuilder);
        //1.3品牌过滤
        if (searchMap.get("brand") != null) {
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("brandName", searchMap.get("brand"));
            //bool查询构造器
            boolQueryBuilder.filter(termQueryBuilder);
        }
        //1.4规格过滤查询   前后端约定：所有spec.开头的参数都是规格 searchMap---前端传过来的参数
        /**
         * #词条查询
         * GET sku/_search
         * {
         *   "query": {
         *     "term": {
         *       "spec.颜色.keyword": "紫色"
         *     }
         *   }
         * }
         */
        for (String key : searchMap.keySet()) {
            if (key.startsWith("spec.")) {                                  //"spec.颜色.keyword": "紫色"
                TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(key + ".keyword", searchMap.get(key));
                boolQueryBuilder.filter(termQueryBuilder);
            }
        }
        //价格过滤 前端传过来的价格 2000-5000
        if (searchMap.get("price") != null) {
            String[] prices = searchMap.get("price").split("-");
            if (!prices[0].equals("0")) {//最低价格
                RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").gte(prices[0] + "00");
                boolQueryBuilder.filter(rangeQueryBuilder);
            }
            if (!prices[1].equals("*")) {//价格上限
                RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").lte(prices[1] + "00");
                boolQueryBuilder.filter(rangeQueryBuilder);
            }

        }

        /**
         * GET sku/_search
         * {
         * "from": 60,
         * "size": 30
         * }
         */
        Integer pageNo = Integer.parseInt(searchMap.get("pageNo"));//获取跳转页码数
        Integer pageSize = 30;//分页大小
        //起始记录下标
        int fromIndex = (pageNo - 1) * pageSize;
        //设置查找分页请求参数
        searchSourceBuilder.from(fromIndex);//开始索引
        searchSourceBuilder.size(pageSize);//页大小

        //排序
//        String sort = searchMap.get("sort");//排序字段
//        String sortOrder = searchMap.get("sortOrder");//排序规则
//        if (!"".equals(sort)) {
//            searchSourceBuilder.sort(sort, SortOrder.valueOf(sortOrder));
//        }

        /**
         *
         * AggregationBuilders：聚合构建器工厂
         * TermsAggregationBuilder：词条聚合构建器
         * Aggregations：分组结果封装
         * Terms.Bucket： 桶
         */
        //聚合查询
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("sku_category").field("categoryName");
        searchSourceBuilder.aggregation(termsAggregationBuilder);

        searchRequest.source(searchSourceBuilder);

        //封装查询结果
        Map resultMap = new HashMap();
        try {
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            SearchHits searchHits = searchResponse.getHits();
            long totalHits = searchHits.getTotalHits();
            System.out.println(totalHits);
            SearchHit[] hitsHits = searchHits.getHits();
            //商品列表
            List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
            for (SearchHit hitsHit : hitsHits) {
                Map<String, Object> sourceAsMap = hitsHit.getSourceAsMap();
                resultList.add(sourceAsMap);
            }
            resultMap.put("rows", resultList);
            //2.2商品分类列表
            Aggregations aggregations = searchResponse.getAggregations();
            Map<String, Aggregation> aggregationMap = aggregations.getAsMap();
            Terms terms = (Terms) aggregationMap.get("sku_category");
            List<? extends Terms.Bucket> buckets = terms.getBuckets();
            List<String> categoryList = new ArrayList<>();
            for (Terms.Bucket bucket : buckets) {
                categoryList.add(bucket.getKeyAsString());
            }
            resultMap.put("categoryList", categoryList);
            //品牌分类列表
            String categoryName = "";//商品分类名称  categoryName
            if (searchMap.get("category") == null) {
                if (categoryList.size() > 0) {
                    //提取分类列表中的第一个分类
                    categoryName = categoryList.get(0);
                }
            } else {
                categoryName = searchMap.get("category");//提取分类中的参数
            }
            //2.3查询品牌列表
            if (searchMap.get("brand") == null) {
                List<Map> brandList = brandMapper.findListByCategoryName(categoryName);
                resultMap.put("brandList", brandList);
            }
            //2.4规格列表
            List<Map> specList = specMapper.findListByCategoryName(categoryName);//规格列表
            for (Map spec : specList) {
                //像素	300万像素,800万像素 ------数据库存储信息为逗号分隔，切分并存入数组中
                String[] options = ((String) spec.get("options")).split(",");
                spec.put("options", options);//将数据库信息取出转换数组格数重新存入List集合
            }
            resultMap.put("specList", specList);

            //2.5接受页码处理，如果不传递页码默认为第一页
            long totalCount = searchHits.getTotalHits();//总记录数
            long pageCount = (totalCount % pageSize == 0) ? (totalCount / pageSize) : (totalCount / pageSize + 1);
            resultMap.put("totalPages", pageCount);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultMap;
    }
}
